<template>
  <div>
    <!-- 面包屑导航区域 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
			<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
			<el-breadcrumb-item>权限管理</el-breadcrumb-item>
			<el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片区域 -->
    <el-card>
      <el-row>
        <el-col>
          <el-button type="primary" @click="addRoleBtn">添加角色</el-button>
        </el-col>
      </el-row>
      <el-table :data="rolesList" stripe border>
        <!-- 展开列 -->
        <el-table-column type="expand">
            <template v-slot="scope">
                <!-- 渲染得到一级权限 -->
							<el-row :class="['borderBottom',i1 === 0 ? 'borderTop' : '','vcenter']" 
							        v-for="(item1,i1) in scope.row.children" :key="item1.id">                      
								<el-col :span="5">
									<el-tag closable @close="removeRights(scope.row,item1.id)">{{item1.authName}}</el-tag>
									<i class="el-icon-caret-right"></i>
								</el-col>
								<el-col :span="19">
									<!-- 渲染得到二级权限 -->
									<el-row :class="[i2 === 0 ? '' : 'borderTop','vcenter']" 
									        v-for="(item2,i2) in item1.children" :key="item2.id">								
										<el-col :span="6">
											<el-tag type="success" closable @close="removeRights(scope.row,item2.id)">{{item2.authName}}</el-tag>   
											<i class="el-icon-caret-right"></i>                         
										</el-col>
										<!-- 渲染三级权限 -->
										<el-col :span="18">
											<el-tag 
												v-for="(item3) in item2.children" :key="item3.id"
												type="warning"
												closable
												@close="removeRights(scope.row,item3.id)">
												{{item3.authName}}
											</el-tag>
										</el-col>
									</el-row>
								</el-col>
							</el-row>
            </template>
        </el-table-column>
            
				<!-- 索引列 -->
				<el-table-column type="index" label="#"></el-table-column>
				<el-table-column prop="roleName" label="角色名称"></el-table-column>
				<el-table-column prop="roleDesc" label="角色描述"></el-table-column>
				<el-table-column label="操作">
						<template v-slot="scope">
								<el-button 
								type="primary" 
								icon="el-icon-edit" 
								size="small"
								@click="editRoleBtn(scope.row.id)">编辑
								</el-button>
								<el-button 
								type="danger" 
								icon="el-icon-delete" 
								size="small"
								@click="deleteRoleBtn(scope.row.id)">删除
								</el-button>
								<el-button 
								type="warning" 
								icon="el-icon-setting" 
								size="small"
								@click="setRightsBtn(scope.row)">分配权限
								</el-button>
						</template>
				</el-table-column>
      </el-table>
    </el-card>

    <!-- 添加角色对话框 -->
    <el-dialog
        title="添加角色"
        :visible.sync="addDialogVisible"
        width="45%"
        @close="addClose">
        <el-form 
            :model="addForm" 
            :rules="addRules" 
            ref="addRuleForm" 
            label-width="100px">
            <el-form-item label="角色名称" prop="roleName">
                <el-input v-model="addForm.roleName"></el-input>
            </el-form-item>
            <el-form-item label="角色描述" prop="roleDesc">
                <el-input v-model="addForm.roleDesc"></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
         <el-button @click="addDialogVisible = false">取 消</el-button>
         <el-button type="primary" @click="addRole">确 定</el-button>
        </span>
    </el-dialog>

    <!-- 编辑角色对话框 -->
    <el-dialog
        title="修改角色"
        :visible.sync="editDialogVisible"
        width="45%"
        @close="editClose">
        <el-form 
            :model="editForm" 
            :rules="editRules" 
            ref="editRuleForm" 
            label-width="100px">
            <el-form-item label="角色名称" prop="roleName">
                <el-input v-model="editForm.roleName"></el-input>
            </el-form-item>
            <el-form-item label="角色描述" prop="roleDesc">
                <el-input v-model="editForm.roleDesc"></el-input>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
         <el-button @click="editDialogVisible = false">取 消</el-button>
         <el-button type="primary" @click="editRole">确 定</el-button>
        </span>
    </el-dialog>

		<!-- 分配角色对话框 -->
		<el-dialog
        title="分配权限"
        :visible.sync="rightsDialogVisible"
        width="45%"			
				@close="rightsClose">
			<el-tree 
				:data="rightsList" 
				:props="rightsProps"
				show-checkbox
				node-key="id"
				default-expand-all
				:default-checked-keys="keysArr"
				ref="treeRef">
			</el-tree>
			<span slot="footer" class="dialog-footer">
         <el-button @click="rightsDialogVisible = false">取 消</el-button>
         <el-button type="primary" @click="setRightsDialog">确 定</el-button>
      </span>
		</el-dialog>
		
  </div>
</template>

<script>
export default {
    name:'Roles',
    data() {
        return {
            rolesList:[],
            addDialogVisible: false,
            addForm:{
                roleName:'',
                roleDesc:''
            },    
            addRules:{
                roleName:[
                     { required: true, message: '请输入角色名称', trigger: 'blur' },
                     { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
                ],
                roleDesc:[
                    { required: true, message: '请输入角色描述', trigger: 'blur' },
                    { min: 3, max: 16, message: '长度在 3 到 16 个字符', trigger: 'blur' }
                ]
            },
            editDialogVisible: false,
            editForm:{
                roleName:'',
                roleDesc:''
            },
            editRules:{
                roleName:[
                     { required: true, message: '请输入角色名称', trigger: 'blur' },
                     { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
                ],
                roleDesc:[
                    { required: true, message: '请输入角色描述', trigger: 'blur' },
                    { min: 3, max: 16, message: '长度在 3 到 16 个字符', trigger: 'blur' }
                ]
            },
						rightsDialogVisible: false, 
						// 所有权限列表
						rightsList:[],       
						rightsProps:{
							// tree展示的属性
							label:'authName',
							// 父子节点嵌套通过的属性
							children:'children'
						}, 
						// 默认选中的节点id值数组
						keysArr:[],
						// 即将分配权限的角色id
						roleId: '',
        }
    },
    created(){
        this.getRolesList()
    },
    methods:{
        // 获取角色列表
        async getRolesList(){
            const {data:res} = await this.$http.get('roles')
            //console.log(res)
            if(res.meta.status !== 200) return this.$message.error('获取角色列表失败')
            this.rolesList = res.data
        },
        // 添加对话框关闭重置表单
        addClose(){
            this.$refs.addRuleForm.resetFields()
        },
        // 添加角色
        addRoleBtn(){
            this.addDialogVisible = true                 
        },
        addRole(){          
            this.$refs.addRuleForm.validate( async value => {
                if(!value) return 
                const {data:res} = await this.$http.post('roles',this.addForm)
                //console.log(res)
                if(res.meta.status !== 201) return this.$message.error('添加角色失败')
                this.$message.success('添加角色成功')
                this.getRolesList()
                this.addDialogVisible = false
            })
        },
        // 编辑对话框关闭重置表单
        editClose(){
            this.$refs.editRuleForm.resetFields()
        },
        // 获取角色信息
        async editRoleBtn(id){           
            const {data:res} = await this.$http.get('roles/' + id)
            //console.log(res)
            if(res.meta.status !== 200) return this.$message.error('获取角色信息失败')
            this.editForm = res.data
            this.editDialogVisible = true
        },
        editRole(){
            this.$refs.editRuleForm.validate( async value => {
                if(!value) return 
                const {data:res} = await this.$http.put('roles/' + this.editForm.roleId,{
                    roleName:this.editForm.roleName,
                    roleDesc:this.editForm.roleDesc
                })
                console.log(res)
                if(res.meta.status !== 200) return this.$message.error('编辑角色失败')
                this.$message.success('编辑角色成功')
                this.getRolesList()
                this.editDialogVisible = false
            })
        },
        // 删除角色
        async deleteRoleBtn(id){
            const result = await this.$confirm('此操作将永久删除该角色, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).catch(error => error)
            if(result !== 'confirm') return this.$message.info('已取消删除角色')
            const {data:res} = await this.$http.delete('roles/' + id)
            if(res.meta.status !== 200) return this.$message.error('删除角色失败')
            this.$message.success('删除角色成功')
            this.getRolesList()
        },
				// 删除角色下指定的权限
				async removeRights(roles,rights_id){
					const result = await this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).catch(error => error)
				    if(result !== 'confirm') {
					    return this.$message.info('取消了删除')
				    }
						const {data:res} = await this.$http.delete(`roles/${roles.id}/rights/${rights_id}`)
						//const {data:res} = await this.$http.delete('roles/' + roles_id + '/rights/' + rights_id)
						if(res.meta.status !== 200) return this.$message.error('删除权限失败')
						console.log(res)
						this.$message.success('删除权限成功')
						// 删除权限后页面不变化，数据更改
						roles.children = res.data
				},
				// 展示分配权限对话框
				async setRightsBtn(role){				
					this.roleId = role.id	
					const {data:res} = await this.$http.get('rights/tree')
					//console.log(res)
					if(res.meta.status !== 200) return this.$message.error('分配权限失败')
					this.rightsList = res.data					
					// 调用递归函数获取三级节点的id
					this.getRightsKeys(role,this.keysArr)
					this.rightsDialogVisible = true
				},
				// 通过递归函数，获取角色下的三级权限id并保存到	keysArr数组
				getRightsKeys(node,arr){
					// 若不包含children属性，则是三级节点，向数组添加id
					if(!node.children){						
						 return arr.push(node.id)
					}
					node.children.forEach( item => 
					   this.getRightsKeys(item,arr))
				},
				rightsClose(){
					this.keysArr = []
					this.rightsDialogVisible = false
				},
				// 分配角色的确定按钮（角色授权）
				async setRightsDialog(){
					const keys = [
						// 以数组形式返回复选框勾选中的权限id
						...this.$refs.treeRef.getCheckedKeys(),
						// 以数组形式返回半选中的权限id
						...this.$refs.treeRef.getHalfCheckedKeys()
					]
					//console.log(keys)
					const idStr = keys.join(',')
					const {data:res} = await this.$http.post('roles/' + this.roleId + '/rights',
					// 请求体
					{rids:idStr})
					if(res.meta.status !== 200) return this.$message.error('分配权限失败')
					this.$message.success('分配权限成功')
					this.getRolesList()
					this.rightsDialogVisible = false 
				}
				
    }
}
</script>

<style lang="less" scoped>
div /deep/ .el-card{
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
  margin-top: 20px;

  .el-table{
      margin-top: 20px;
  }
}
.el-tag{
      margin: 6px;
  }
.borderBottom{
    border-bottom: 1px solid #aaa;
}
.borderTop{
    border-top: 1px solid #aaa;
}
.vcenter{
	display: flex;
	align-items: center;
}
</style>